# -*- coding: utf-8 -*-

import random
# 用于读取csv文件并创建决定表的函数
def read_decision_table_from_csvfile(file):
    with open(file, "r") as fileobj:
        dt = []  # 初始化表示决定表的列表
        for num_obj, row in enumerate(fileobj):
            # 删除换行和空白等多余字符
            row = row.strip()
            tmp = row.split(",")
            tmp2 = []
            # 将决定表中的值转换为int型
            for value in tmp:
                if value.isdigit() == True:
                    tmp2.append(int(value))
                else:
                    tmp2.append(value)
            # 将行作为元组添加到dt
            dt.append(tuple(tmp2))
        #num_attr =len(dt[0]) - 1  # 属性个数为列数-1
        #numbers = tuple(range(0, num_attr+1))  # 选择表示属性编号的元组
        #dt.insert(0, numbers)                  # 插入到决定表的开头
        return dt

# 根据属性id的集合attributes ids创建全体集合的分割的函数
def make_partition(dt, attributes_ids):
    partition = []
    univ_ids = set(range(1, len(dt)))  # 目标id的集合（工作用）
    while True:
        eq = set()  # 初始化要创建的同值类
        try:
            item = univ_ids.pop()  # 取出一个对象id
        except KeyError:
            break  # 因为univ ids变空了，所以作业结束
        except:
            print("Error!")
            return None
        eq.add(item)  # 添加item
        # 在attributes ids中包含的所有属性中，寻找与item值相同的对象
        for element in univ_ids:
            flag = True  # 假设element和item值相等
            for attr in attributes_ids:
                # 检查属性attra的值
                if dt[element][attr] != dt[item][attr]:
                    flag = False  # 因为element和item的attr值不同
                    break         # 对element的处理结束
            if flag == True:     # 因为element和item的值真的是相等的
                eq.add(element)  # element是item的同类要素
        # 因为item的同值类eq完成了，所以追加到partition
        partition.append(eq)
        # 因为没有必要调查eq的要素，所以从univ ids中删除
        univ_ids.difference_update(eq)
    return partition    # 列表

# 决定表dt的分割partition创建正区域pos的函数
def make_positive_region(dt, partition, dec_class):
    pos = set()  # 初始化正区域
    # 寻找包含partition中包含的同值类的决定类
    for eq in partition:
        for dc in dec_class:
            if eq.issubset(dc):  # 如果等值类eq包含在确定类dc中
                pos.update(eq)   # eq的元素包含在正区域中
    return pos

# 通过划分partition计算近似质量的函数
def calc_quality_of_approximation_by_partition(dt, partition, dec_class):
    pos = make_positive_region(dt, partition, dec_class)  # 创建正则区域
    return len(pos) / (len(dt)-1)  # 近似质量=正区域元素数/决定表元素数


